home *** CD-ROM | disk | FTP | other *** search
/ Loadstar 224 / 224.d81 / t.dir to bas < prev    next >
Text File  |  2022-08-26  |  8KB  |  303 lines

  1. u
  2.           DIRECTORY TO BASIC
  3.            by Dave Moorman
  4.  
  5.  
  6.     There are two ways to bring a
  7. directory into Basic that I won't use
  8. today. The first is to load up a good
  9. toolbox module such as MR.MOUSE and
  10. use its Directory features. But for
  11. this tutorial, I want to show a
  12. couple of things. So we will
  13. "re-invent" the wheel -- so to speak.
  14.  
  15.     The other method is to OPEN the
  16. directory with an OPEN statement, then
  17. use GET# to bring in the text, one
  18. character at a time. This oft touted
  19. technique has two problems:
  20.  
  21. 1. It is slower than molasses on a
  22. cold morning, and
  23.  
  24. 2. It uses string concatenation, which
  25. I would rather avoid as much as
  26. possible.
  27.  
  28.     As an alternative, I will Bload
  29. the directory into memory. To put the
  30. bytes into a string, I will show a
  31. much faster method.
  32.  
  33.     The program here is designed to go
  34. through a disk directory looking for
  35. files with "L/D." prefixes and Rename
  36. them to have "LD." prefixes. This is
  37. in response to the problem Stephen
  38. Beigle found after using Letter Drop
  39. Writer to create quotes for Letter
  40. Drop. Writer saves files with "L/D."
  41. prefixes, while Letter Drop reads only
  42. files with "LD." prefixes.
  43.  
  44.     So, if you don't want to learn
  45. anything, just run the Run It program.
  46. At the prompt, put a disk full of
  47. Letter Drop Writer quotes (L/D.) in a
  48. drive and choose the drive number from
  49. the menu. In a minute, your files will
  50. all be renamed.
  51.  
  52.     However, if you want to find out
  53. how it is done, stick around!
  54.  
  55.  
  56. THE PROGRAM
  57.  
  58.     The first lines are fairly
  59. standard around the Tower.
  60.  
  61. 5 IFPEEK(56)<>64THENPOKE56,64:RUN
  62.  
  63.     This line sets the Top of Basic to
  64. Page 64, giving a lot of free memory
  65. for the Directory.
  66.  
  67. 10 D=PEEK(186):IFD<8THENSTOP
  68.  
  69.     Of course, make D the current
  70. device. On the Run It version, I added
  71. a Menu to allow changing disks.
  72.  
  73. 20 DEFFNH(X)=INT(X/256)
  74. 21 DEFFNL(X)=X-FNH(X)*256
  75.  
  76.     These two defined functions will
  77. divide a memory location into two
  78. bytes. There are lots of ways of doing
  79. this. I think it is more elegant to
  80. use FNH(x) and FNL(x) in the body of
  81. the program.
  82.  
  83.  
  84. 100 REM MAKE A$ A MOVEABLE STRING
  85. 101 A$=STR$(PEEK(71)+256*PEEK(72))
  86. 102 A=VAL(A$)
  87.  
  88.     Now this bit of code may look odd.
  89. String variables do not directly hold
  90. their string content. They are set up
  91. right along with all other variables,
  92. with two bytes for the variable name
  93. and five bytes for content. Strings
  94. only use three of the five bytes --
  95. for Length, Address Low, and Address
  96. Hi. These two Address bytes point to
  97. the actual contents of the variable.
  98.  
  99.     Back when I used my TRS-80 Model
  100. I, Level II Basic (also by Microsoft),
  101. I found a function called STRPTR(v),
  102. which returned the first byte of the
  103. three-byte pointer for variable v.
  104. Alas, Basic 2.0 does not have STRPTR.
  105. But we do have a very well explored
  106. zero page. And the variable pointers
  107. are pointed to by locations 71/72.
  108.  
  109.     Now the pointer pointer is a very
  110. busy place. Capturing the value there
  111. is tricky, especially for string
  112. variables. So I found a dodge. (I
  113. wanted a Plymouth, but a Dodge will
  114. do!) Look carefully above. The value
  115. in 71/72 is put in a STR$ and put into
  116. A$. That value is the location of the
  117. A$s pointer. I put the VAL(A$) into A,
  118. and now
  119.  
  120.      A holds LENGTH
  121.      A+1 holds the LO BYTE
  122.      A+2 holds the HI BYTE
  123.  
  124.     The beautiful thing about how a
  125. Microsoft Basic handles string
  126. variable is that when you POKE values
  127. into these three bytes, A$ will
  128. "contain" whatever A bytes start at
  129. A+1/A+2. You can't look under ROM with
  130. this, but any other memory can be very
  131. quickly grabbed into a string
  132. variable.
  133.  
  134. 110 F$="L/D.":F=LEN(F$)+1:REM FIND STR
  135. ING
  136. 120 T$="LD.":T=LEN(T$)+1:REM TO STRING
  137.  
  138.     To simplify the code, I put the
  139. FROM prefix in F$ and the TO prefix
  140. into T$, with F and T holding the
  141. length of each (plus 1). As I was
  142. testing, I could easily swap the two
  143. patterns, changing the disk from
  144. "L/D." files to "LD." files and vice
  145. versa.
  146.  
  147.  
  148. 149 REM BLOAD DIRECTORY
  149. 150 SYS57812"$:"+F$+"*",D,0:POKE780,0
  150. :POKE781,0:POKE782,64 :SYS65493
  151.  
  152.     If you don't have this code all
  153. but memorized, you haven't done enough
  154. programming! To Bload a directory in a
  155. format you can read, be sure the
  156. secondary address (the ,0) is 0.
  157.  
  158.  
  159. 159 REM BEGIN AT 64*256 & SKIP HEADER
  160. 160 L=64*256+32
  161. 161 L1=2       :REM SKIP 2 BYTES
  162. 162 L2=16      :REM LENGTH OF FILENAME
  163.  
  164.     Once the directory is in memory at
  165. Page 64, we need to point to it. Note
  166. -- I [think] in memory pages, which is
  167. why I use 64*256. Who can remember
  168. every page's full memory number?
  169. Also, in this situation, the Header is
  170. not needed, so we add 32 in order to
  171. just skip it.
  172.  
  173.     L1 is set to 2 because the first
  174. two bytes of a directory line hold the
  175. block count as a two-byte integer. We
  176. are going to skip these. However, if
  177. you want to get the block size, use
  178. the following:
  179.  
  180. DEFFNI(X)=PEEK(X)+256*PEEK(X+1)
  181.  
  182. BS=FNI(L)
  183.  
  184.     BS will hold the Block Size of the
  185. file.
  186.  
  187.  
  188. 163 REM CHECK FOR "BLOCK" --END OF DIR
  189. 164 POKEA,5:POKEA+1,FNL(L+L1):POKEA+2,
  190. FNH(L+L1):IFA$="BLOCK"THENEND
  191.  
  192.     Any good processing program must
  193. know when to quit. With a directory,
  194. when you get to BLOCKS FREE, you know
  195. you are done. So here we use the
  196. A$-Gambit. We need a 5 byte long
  197. string, beginning with location L+L1.
  198. By POKEing the Length, LOW, and HIGH
  199. into A, A+1, A+2, we make A$ "look" at
  200. the particular directory line.
  201.  
  202.  
  203. 169 REM FIND FIRST QUOTE MARKS
  204. 170 IFPEEK(L+L1)<>34THENL1=L1+1:
  205. GOTO170
  206. 175 L1=L1+1
  207.  
  208.     Long ago, in the ancient days of
  209. the PET, someone at Microsoft decided
  210. to save some precious ROM by using the
  211. LIST routine to display the Directory.
  212. It was a clever answer for 1976. Then
  213. CBM built the C-64 in an unprecidented
  214. [TWO MONTHS], and to get the machine
  215. out the door, they just copied Basic
  216. 2.0. This is why the Block Size is a
  217. two-byte value rather than the actual
  218. numbers.
  219.  
  220.     When you LIST the Directory, the
  221. Line Number routine generates the
  222. Block Size. But in order to have the
  223. Filenames line up nice and straight,
  224. some Space characters are used to pad
  225. the line before the quote mark. Nice
  226. for them -- a pain for us! In line 170
  227. above, L1 in incremented until a quote
  228. (34) is found, then incremented once
  229. more. L+L1 now points to the beginning
  230. of the filename.
  231.  
  232.  
  233. 179 REM FIND LENGTH TO 2ND QUOTE MARKS
  234. 180 IFPEEK(L+L1+L2)<>34THENL2=L2-1:GOT
  235. o180
  236.  
  237.     Likewise, the filename might be 16
  238. characters long -- or not. So we
  239. decrement L2 to find the end quote
  240. marks.
  241.  
  242.  
  243. 189 REM POKE LEN, LO, HI INTO A
  244. 190 POKEA,L2:POKEA+1,FNL(L+L1):POKEA+2
  245. ,FNH(L+L1)
  246.  
  247.     Once we have the Length and
  248. Location of the text, we can POKE the
  249. values into the A$ pointer.
  250.  
  251.  
  252. 191 REM SCRUB OFF PREFIX
  253. 192 A$=MID$(A$,F):PRINTA$
  254.  
  255.     Now, I [could] have just added 5
  256. to L+L1 in line 90. This is more
  257. transparent. We remove the prefix from
  258. A$.
  259.  
  260.  
  261. 193 REM RENAME TO NEW PREFIX
  262. 194 OPEN15,D,15,"R0:"+T$+A$+"="+F$+A$:
  263. CLOSE15
  264.  
  265.     And finally, we can do the Rename.
  266. All that work for just one functional
  267. line! On the otherhand, you could do
  268. all the Renames in Immediate Mode,
  269. like Stephen did.
  270.  
  271.  
  272. 198 REM ADD 32 TO LOCATION
  273. 199 L=L+32:GOTO161
  274. 999 end
  275.  
  276.     And lastly, we add 32 to L to
  277. point to the next line, and go to line
  278. 161 to do it again.
  279.  
  280.  
  281. 10000 D=PEEK(186):N$="B.DIR TO BAS":
  282. OPEN1,D,15,"I0":CLOSE1
  283. 10001 OPEN1,D,15,"S0:"+N$:CLOSE1:
  284. SAVEN$,D:END
  285.  
  286.     I wanted to show you how I now do
  287. the Scratch and Save routine. The "I0"
  288. is just a safety measure, making sure
  289. the drive is set and ready to work
  290. right. I have had a couple of
  291. "accidents" that could have been
  292. solved by using this one more disk
  293. command.
  294.  
  295.     Well, that's it. I never cease to
  296. be amazed at how ingenius and
  297. club-footed Basic 2.0 is! But since
  298. everything is [always] logical, one
  299. can logically get around any problem!
  300.  
  301.  DMM
  302.  
  303.  
  304.